package main

import (
	"fmt"
	"reflect"
)

type Profile struct {
	name   string
	age    int
	gender string
}

func (p Profile) SayBye() {
	fmt.Println("Bye")
}

func (p Profile) SayHello() {
	fmt.Println("Hello")
}

func main() {
	m := Profile{}

	t := reflect.TypeOf(m)
	fmt.Println("Type: ", t)
	fmt.Println("Kind: ", t.Kind())

	t = reflect.TypeOf(&m)
	fmt.Println("&m Type: ", t)
	fmt.Println("&m Kind: ", t.Kind())

	fmt.Println("m Type: ", t.Elem())
	fmt.Println("m Kind: ", t.Elem().Kind())

	v := reflect.ValueOf(&m)

	fmt.Println("&m Type: ", v.Type())
	fmt.Println("&m Kind: ", v.Kind())

	fmt.Println("m Type: ", v.Elem().Type())
	fmt.Println("m Kind: ", v.Elem().Kind())

	age := 25
	v1 := reflect.ValueOf(age)
	fmt.Printf("转换前, type: %T, value: %v \n", v1, v1)
	v2 := v1.Int()
	fmt.Printf("转换后, type: %T, value: %v \n", v2, v2)

	score := 99.5
	v3 := reflect.ValueOf(score)
	fmt.Printf("转换前, type: %T, value: %v \n", v3, v3)
	v4 := v3.Float()
	fmt.Printf("转换后, type: %T, value: %v \n", v4, v4)

	var name string = "Go编程时光"
	v5 := reflect.ValueOf(name)
	fmt.Printf("转换前， type: %T, value: %v \n", v5, v5)
	v6 := v5.String()
	fmt.Printf("转换后， type: %T, value: %v \n", v6, v6)

	var isMale bool = true
	v7 := reflect.ValueOf(isMale)
	fmt.Printf("转换前， type: %T, value: %v \n", v7, v7)
	v8 := v7.Bool()
	fmt.Printf("转换后， type: %T, value: %v \n", v8, v8)

	v9 := reflect.ValueOf(&age)
	fmt.Printf("转换前， type: %T, value: %v \n", v9, v9)
	v10 := v9.Pointer()
	fmt.Printf("转换后， type: %T, value: %v \n", v10, v10)

	v11 := reflect.ValueOf(age)
	fmt.Printf("转换前， type: %T, value: %v \n", v11, v11)
	v12 := v11.Interface()
	fmt.Printf("转换后， type: %T, value: %v \n", v12, v12)

	numList := []int{1, 2}
	v13 := reflect.ValueOf(numList)
	fmt.Printf("转换前， type: %T, value: %v \n", v13, v13)
	v14 := v13.Slice(0, 2)
	fmt.Printf("转换后， type: %T, value: %v \n", v14, v14)

	v15 := reflect.ValueOf(&numList).Elem()
	v15.Set(reflect.Append(v15, reflect.ValueOf(3)))
	fmt.Println(v15, " ", v15.Len())
	fmt.Println(numList, " ", len(numList))

	p1 := Profile{"写代码的Misiro", 27, "male"}
	v16 := reflect.ValueOf(p1)
	fmt.Println("字段数: ", v16.NumField())
	for i := 0; i < v16.NumField(); i++ {
		fmt.Printf("第%d个字段: %v \n", i+1, v16.Field(i))
	}

	p2 := &Profile{"写代码的Misiro", 27, "male"}
	t17 := reflect.TypeOf(p2).Elem()
	v17 := reflect.ValueOf(p2).Elem()
	fmt.Println("方法数(可导出的): ", t17.NumMethod())
	for i := 0; i < t17.NumMethod(); i++ {
		fmt.Printf("第%d个方法: %v \n", i+1, t17.Method(i).Name)
		v17.Method(i).Call(nil)
	}

}
